import csv
from pyproj import Transformer
from random import randint
from phe import paillier
import math

Rmax = 3

def genRandom(n,low=0,high=100):
    ret = []
    st = set()
    for i in range(n):
        while True:
            x = 1.0*randint(low*10**6, high*10**6) / 10**6
            # y = 1.0*randint(low*10**6, high*10**6) / 10**6
            # t = (x, y)
            t = int(x)
            if t not in st:
                break
        ret.append(t)
        st.add(t)
    return ret

def sampleTasks(m, n, tids, per):
    curPer = int( math.ceil(m*1.0/n) )
    _tids = []
    for i in range(n):
        for j in range(curPer):
            if j>=int(curPer*0.7):
                k = i*per + int(per*0.7) + j - int(curPer*0.7)
            else:
                k = i*per + j
            tid = tids[k]
            _tids.append(tid)
    return _tids[:m]

def read():
    fileNameTask = "demand_2016.08.09_610100_.csv"
    fileNameWorker = "distribute_2016.08.09_610100_.csv"
    transformer = Transformer.from_crs(crs_from="EPSG:4326",crs_to="EPSG:4087")#将GPS坐标转化为平面坐标
    
    longlist=[]
    latlist=[]

    lonratio = 1
    latratio = 1

    with open(file=fileNameTask,mode='r',encoding='utf-8') as f:
        coordinateTask=[]
        fdata = csv.reader(f)
        next(fdata)
        for i in fdata:
            hour = float(i[1])
            longitude = float(i[2])
            latitude = float(i[3])
            
            # if longitude < 114:
                # tr = transformer.transform(latitude,longitude)#latitude,longitude 是纬经度，而是不是默认的经纬度
                # coordinateTask.append([tr[1],tr[0]])
            if hour < 10:
                tr = transformer.transform(latitude,longitude)#latitude,longitude 是纬经度，而是不是默认的经纬度,但是输出是经纬度
                coordinateTask.append([tr[0]/lonratio,tr[1]/latratio])

    with open(file=fileNameWorker,mode='r',encoding='utf-8') as f:
        coordinateWork=[]
        fdata = csv.reader(f)
        next(fdata)
        for i in fdata:
            hour = float(i[1])
            longitude = float(i[2])
            latitude = float(i[3])
            # if longitude < 114:
            #     tr = transformer.transform(latitude,longitude)#latitude,longitude 是纬经度，而是不是默认的经纬度
            #     coordinateWork.append([tr[0]/10000,tr[1]/1000])
            if hour < 10:
                tr = transformer.transform(latitude,longitude)#latitude,longitude 是纬经度，而是不是默认的经纬度
                coordinateWork.append([tr[0]/lonratio,tr[1]/latratio])
    

    with open("../testdata.txt",mode='w',encoding='utf-8') as f:
        workerNum = len(coordinateWork)
        taskNum = len(coordinateTask)
        sumNum = workerNum+taskNum
        f.write(str(workerNum)+" "+str(taskNum)+" "+str(sumNum)+"\n")
        for longitude,latitude in coordinateTask:
            wstr = "t "+str(longitude)+" "+str(latitude)
            f.write(wstr+"\n")
        for longitude,latitude in coordinateWork:
            wstr = "w "+str(longitude)+" "+str(latitude)+" 500"
            f.write(wstr+"\n")

def test(day):
    coordinateTask=[]
    coordinateWorker=[]
    for d in day:
        fileNameTask = "demand_2016.08."+d+"_610100_.csv"
        fileNameWorker = "distribute_2016.08."+d+"_610100_.csv"
        fileNameMoney = "money_2016.08."+d+"_610100_.csv"
        transformer = Transformer.from_crs(crs_from="EPSG:4326",crs_to="EPSG:4087")#将GPS坐标转化为平面坐标
        with open(file=fileNameTask,mode='r',encoding='utf-8') as f:
            fdata = csv.reader(f)
            next(fdata)
            for i in fdata:
                hour = float(i[1])
                longitude = float(i[2])
                latitude = float(i[3])
                tr = transformer.transform(latitude,longitude)
                # coordinateTask.append(tr)
                coordinateTask.append([tr[0]/1000,tr[1]/1000])
        with open(file=fileNameWorker,mode='r',encoding='utf-8') as f:
            fdata = csv.reader(f)
            next(fdata)
            for i in fdata:
                hour = float(i[1])
                longitude = float(i[2])
                latitude = float(i[3])
                tr = transformer.transform(latitude,longitude)
                # coordinateWorker.append(tr)
                coordinateWorker.append([tr[0]/1000,tr[1]/1000])
    # with open(file=fileNameMoney,mode='r',encoding='utf-8') as f:
    #     coordinateMoney=[]
    #     fdata = csv.reader(f)
    #     next(fdata)
    #     for i in fdata:
    #         hour = float(i[1])
    #         longitude = float(i[2])
    #         latitude = float(i[3])
    #         coordinateMoney.append([longitude,latitude])
    
    #get workers

    wids = genRandom(2000,0,len(coordinateWorker))
    wids = sorted(wids)
    tids = []
    per = 5
    notworker = []
    wTemp = []
    for wid in wids:
        worker = coordinateWorker[wid]
        flag = 0
        tTemp = []
        for tid in range(len(coordinateTask)):
            if flag >= per:
                break
            task = coordinateTask[tid]
            d = ((task[0]-worker[0])**2+(task[1]-worker[1])**2)**(1/2)
            if d <=Rmax and tid not in tids:
                flag+=1
                tTemp.append(tid)
        if flag == per:
            for t in tTemp:
                tids.append(t)
            wTemp.append(wid)
        else:
            for i in range(per):
                notworker.append(wid)
            

    print(len(wids),len(wTemp),len(tids),len(notworker))
    # wids = wTemp
    # taskList = []
    # workerList = []
    # n=0
    # for task in coordinateTask:
    #     if task not in taskList:
    #         for worker in coordinateWorker:
    #             d = ((task[0]-worker[0])**2+(task[1]-worker[1])**2)**(1/2)
    #             if d < 5 and worker not in workerList:
    #                 n+=1
    #                 taskList.append(task)
    #                 workerList.append(worker)
    #                 # break
    # print(n,len(taskList),len(workerList))
    
    # nums = [100,500,1000,1500]
    # for i in nums:
    #     ratio = 0.9
    #     filname = "../"+str(i)+"_"+str(i)+"_"+"data.txt"
    #     wids = genRandom(i,0,len(coordinateWorker))
    #     tids = genRandom(i,0,len(coordinateTask))
    #     with open(filname,"w",encoding="utf-8") as f:
    #         f.write(str(i)+" "+str(i)+" "+str(i+i)+"\n")
    #         for j in range(i):
    #             if j <= i*ratio:
    #                 longitude1,latitude1 = taskList[j]
    #                 tstr = "t "+str(longitude1)+" "+str(latitude1)+"\n"
    #                 f.write(tstr)
    #                 longitude2,latitude2 = workerList[j]
    #                 wstr = "w "+str(longitude2)+" "+str(latitude2)+" 3\n"
    #                 f.write(wstr)
    #             else:
    #                 longitude1,latitude1 = coordinateTask[tids[j]]
    #                 tstr = "t "+str(longitude1)+" "+str(latitude1)+"\n"
    #                 f.write(tstr)
    #                 longitude2,latitude2 = coordinateWorker[wids[j]]
    #                 wstr = "w "+str(longitude2)+" "+str(latitude2)+" 3\n"
    #                 f.write(wstr)
    nums = [100,500,1000,1500]
    for i in nums:
        filname = "../"+str(i)+"_"+str(i)+"_"+"data.txt"
        wnum = i
        tnum = i
        _wids = wids[:wnum]
        _tids = sampleTasks(tnum,wnum,tids,per)
        print(len(_wids),len(_tids))
        with open(filname,"w",encoding="utf-8") as f:
            f.write(str(wnum)+" "+str(tnum)+" "+str(wnum+tnum)+"\n")
            for j in range(i):
                windex = _wids[j]
                tindex = _tids[j]
                longitude1,latitude1 = coordinateWorker[windex]
                longitude2,latitude2 = coordinateTask[tindex]
                wstr = "w "+str(longitude1)+" "+str(latitude1)+" "+str(Rmax)+"\n"
                tstr = "t "+str(longitude2)+" "+str(latitude2)+"\n"
                f.write(wstr)
                f.write(tstr)

    
    

def paillierTest():
     public_key, private_key = paillier.generate_paillier_keypair(n_length=5)
     e1 = public_key.encrypt()
     private_key.decrypt()
     paillier.EncryptedNumber()

if __name__ =="__main__":
    # read()
    day = ["06","07","08","09","10","11","12"]
    # day = ["12"]

    test(day)